package com.app.common.adapter

import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

abstract class SelectionAdapter<D : Any, VH : SelectionViewHolder>(private val event: Event<D>) :
    GroupAdapter<D, SelectionViewHolder>() {

    private val selector = ItemSelector<D>(items)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SelectionViewHolder {
        val viewHolder = super.onCreateViewHolder(parent, viewType)
        if (viewType != GROUP) {
            viewHolder.itemView.setOnClickListener(onItemClick)
        }
        return viewHolder
    }


    override fun getItemCount(): Int = items.size

    override fun onBindViewHolder(holder: SelectionViewHolder, position: Int) {
        val item = items[position]
        holder.bindData(item)
        holder.onSelectView(selectView)
        holder.onSelect(selector.isSelected(position))
        if (getItemViewType(position) != GROUP) {
            onBindViewHolder(holder as VH, position, item, "")
        }

        //onBindViewHolder(holder,position,item,"")
    }

    abstract fun onBindViewHolder(holder: VH, position: Int, item: D, payload: String)
    override fun onBindViewHolder(
        holder: SelectionViewHolder,
        position: Int,
        payloads: MutableList<Any>
    ) {
        if (payloads.isNotEmpty()) {
            //val op = payloads.first().toString()
            payloads.forEach {
                val op = it.toString()
                if (op == optSelect) {
                    holder.onSelect(selector.isSelected(position))
                    holder.onSelectView(selectView)
                } else if (getItemViewType(position) != GROUP) {
                    onBindViewHolder(holder as VH, position, items[position], op)
                }
            }

        } else {
            super.onBindViewHolder(holder, position, payloads)
        }
    }

    private var selectView = false
    private val optSelect = "optSelect"

    fun setSelectView(on: Boolean) {
        selectView = on
        if (!on) {
            selector.reset()
        }
        notifyItemRangeChanged(0, itemCount, optSelect)
    }

    fun setItemSelectValue(position: Int, selected: Boolean) {
        selector.setSelectValue(position, selected)
        notifyItemChanged(position, optSelect)
    }

    fun selectAll() {
        selector.selectAll()
        event.onItemSelectedChange(getItemList().size)
        notifyItemRangeChanged(0, itemCount, optSelect)
    }

    fun unSelectAll() {
        selector.unSelectAll()
        event.onItemSelectedChange(0)
        notifyItemRangeChanged(0, itemCount, optSelect)
    }

    fun getSelectedItems(): List<D> {
        println("getSelectedItems  items=${items.size} $items")
        return selector.selectedItems
    }

    fun getItemList(): List<D> {
        return items.filter {
            !isGroupItem(it)
        }
    }

    fun clean() {
        items.clear()
        selector.reset()
        notifyDataSetChanged()
    }

    private fun getItemPos(position: Int): Int {
        var groupCount = 0
        var index = 0
        for (item in items) {
            if (index >= position) {
                break
            }
            if (isGroupItem(item)) {
                groupCount++
            }
            index++
        }

        return position - groupCount
    }

    fun selectedItemCount(): Int = selector.selectedItemCount()
    private var recyclerView: RecyclerView? = null
    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        super.onAttachedToRecyclerView(recyclerView)
        this.recyclerView = recyclerView
    }

    private val onItemClick = View.OnClickListener {
        println("onItemClick  pos=${recyclerView?.getChildAdapterPosition(it) ?:-1}")
        val pos = recyclerView?.getChildAdapterPosition(it) ?: return@OnClickListener
        if (selectView) {
            setItemSelectValue(pos, !selector.isSelected(pos))
            event.onItemSelectedChange(selector.selectedItemCount())
        } else {
            event.onItemClick(getItemPos(pos), items[pos])
        }
        println("selectView=$selectView onItemClick  pos=${selector.isSelected(pos)}")
    }

    interface Event<D> {
        fun onItemSelectedChange(selectedCount: Int)
        fun onItemClick(position: Int, item: D)
    }
}